#ifndef OA_CORE_ENGINE_H
#define OA_CORE_ENGINE_H

#include "libs.h"
#include "util.h"
#include "core/log.h"
#include "core/config.h"
#include "core/event.h"
#include "core/system.h"
#include "core/taskmanager.h"
#include "core/clock.h"
#include "video/video.h"
#include "input/input.h"
#include "app/application.h"

namespace core {
	class _OA_export Engine {
	public:
		typedef boost::shared_ptr<System> SystemPtr;
		typedef std::map<std::string, SystemPtr> SystemMap;

		Engine();
		~Engine();

		void run();
		void stop();

		void setApplication(const boost::shared_ptr<app::Application>& application);

		void add(SystemPtr system);
		bool remove(SystemPtr system);
		SystemPtr load(const std::string& name);
		SystemPtr get(const std::string& name) const;

		TaskManager& getTaskManager();

		const boost::shared_ptr<app::Application>& application();

		const boost::shared_ptr<Config>& config();
		boost::program_options::options_description& settings();		

		const boost::shared_ptr<core::Clock>& clock();
		const boost::shared_ptr<video::Video>& video();
		const boost::shared_ptr<input::Input>& input();
		EventChannel& events();

	private:
		void initializeSystems();
		void shutdownSystems();

		boost::shared_ptr<app::Application> mApplication;

		boost::shared_ptr<Config> mConfig;
		boost::shared_ptr<video::Video> mVideo;
		boost::shared_ptr<input::Input> mInput;
		boost::shared_ptr<core::Clock> mClock;

		SystemMap mSystemMap;
		TaskManager mTaskManager;
		EventChannel mChannel;
	};
}

//extern core::Engine gEngine;

#endif
